#ifndef PSO_H
#define PSO_H

#include <QList>

#include "neuralnetwork.h"
#include "particle.h"

class Pso : public QObject
{
   Q_OBJECT
    
   public:
      Pso();
      Pso( const Pso &pso );
      Pso &operator=( const Pso &pso );
      
      enum InertiaWeightType
      {
	 CONSTANT,
	 TIME_VARIANT
      };
      
      enum Algorithm
      {
	 PSO,
	 RPSO
      };
      
      void setAlgorithm( int algorithm = PSO );
      
      void addToSwarm( NeuralNetwork ann );
      void addToSwarm( Particle p );
      
      void clearSwarm();
      void clearTrainingSet();
      
      void addTrainingSet( const QList< float > &input, const QList< float > &target );
      void addTrainingSet( const QList< float > &set, int splitPoint );
      int trainingSetSize();
      
      void optimize();
      void stopOptimizing();
      
      NeuralNetwork bestNetwork();
      Particle bestParticle();
      
      void setMaxV( float v );
      void setMaxX( float x );
      void setMaxIterations( int iter=10 );
      void setCutoff( float cutoff );
      void setWeight( float weight );
      void setInertiaWeightType( int type = TIME_VARIANT );
      
   signals:
      void sampleCompleted( int sample );
      void iterationCompleted( int iter );
      void newBestFitnessFound( double fitness );
      
   private:
      float m_maxV;
      float m_maxX;
      int m_maxIter;
      float m_cutoff;
      float m_weight;
      int m_weightType;
      
      float m_bestFitness;
      int m_bestFitnessParticleIndex;
      
      bool m_finish;
      
      int m_algorithm;
      
      QList< Particle > m_swarm;
      
      QList< QList< float > > m_inputSet;
      QList< QList< float > > m_targetSet;
};

#endif // PSO_H
